package com.xzy.rabbit.demo.confirmpublish;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.xzy.rabbit.common.util.RabbitUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 发布确认
 *
 * @author xzy
 * @date 2021/9/3016:03
 */
@Slf4j
class Main {

    /**
     * 发送的消息总数
     */
    private static final Integer MESSAGE_COUNT = 3;
    /**
     * 发送每条消息的延迟时间
     */
    private static final long WORK_TIME = 1000L;
    /**
     * 交换机名称
     */
    private static final String EXCHANGE_NAME = "exchange.confirm";
    private static final String EXCHANGE_NAME_NOT_EXIST = "exchange.confirm.false";
    /**
     * 队列名称
     */
    private static final String QUEUE_NAME = "queue.confirm";
    /**
     * 路由键
     */
    private static final String ROUTING_KEY = "confirm";
    private static final String ROUTING_KEY_NOT_EXIST = "confirm.false";

    /*
     * Producer --key--> [Exchange] --key--> [Queue] ----> Consumer
     */

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        // 1.获取连接
        Connection connection = RabbitUtil.getConnection();

        // 2.准备执行环境
        prepare(connection);

        // 3.发送消息

        // ① Exchange存在 + RoutingKey有效
        Thread producer1 = new Thread(new Producer(connection, EXCHANGE_NAME, ROUTING_KEY, MESSAGE_COUNT, WORK_TIME), "producer1");

        // ② Exchange存在 + RoutingKey无效（指无法使消息路由到有效队列）
        Thread producer2 = new Thread(new Producer(connection, EXCHANGE_NAME, ROUTING_KEY_NOT_EXIST, MESSAGE_COUNT, WORK_TIME), "producer2");

        // ③ Exchange不存在 + RoutingKey有效
        Thread producer3 = new Thread(new Producer(connection, EXCHANGE_NAME_NOT_EXIST, ROUTING_KEY, MESSAGE_COUNT, WORK_TIME), "producer3");


        producer1.start();
        producer2.start();
        producer3.start();

        producer1.join();
        producer2.join();
        producer3.join();
    }

    /**
     * 准备执行环境：交换机、队列、绑定
     */
    public static void prepare(Connection connection) throws IOException {
        // 1.获取信道
        Channel channel = connection.createChannel();

        // 2.声明交换机
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);

        // 3.声明队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        // 4.绑定交换机
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY);
    }
}
